package cn.iocoder.yudao.module.system.controller.admin.gugu;

import cn.iocoder.yudao.framework.common.pojo.CommonResult;
import cn.iocoder.yudao.module.system.controller.admin.gugu.gugu.MajorAdmissionInfo;
import cn.iocoder.yudao.module.system.controller.admin.gugu.gugu.MajorAdmissionQueryReqVO;
import cn.iocoder.yudao.module.system.controller.admin.gugu.gugu.MajorAdmissionQueryRespVO;
import cn.iocoder.yudao.module.system.service.gugu.MajorAdmissionService;
import cn.iocoder.yudao.module.system.util.gugu.GuGuDataUtils;
import io.swagger.v3.oas.annotations.Operation;
import io.swagger.v3.oas.annotations.Parameter;
import io.swagger.v3.oas.annotations.tags.Tag;
import lombok.extern.slf4j.Slf4j;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import javax.validation.Valid;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

/**
 * 历年高考专业录取数据查询控制器
 */
@Tag(name = "管理后台 - 历年高考专业录取数据查询")
@RestController
@RequestMapping("/system/major-admission")
@Validated
@Slf4j
public class MajorAdmissionController {

    @Resource
    private MajorAdmissionService majorAdmissionService;

    @GetMapping("/query")
    @Operation(summary = "查询历年高考专业录取数据")
    public CommonResult<MajorAdmissionQueryRespVO> queryMajorAdmission(
            @Parameter(description = "页码，不传默认获取所有数据") @RequestParam(value = "pageIndex", required = false) @Min(value = 1, message = "页码不能小于1") Integer pageIndex,
            @Parameter(description = "每页数据量，不传默认获取所有数据") @RequestParam(value = "pageSize", required = false) @Min(value = 10, message = "每页数据量不能小于10") @Max(value = 50, message = "每页数据量不能大于50") Integer pageSize,
            @Parameter(description = "招生省份") @RequestParam(value = "enrollProvince", required = false) String enrollProvince,
            @Parameter(description = "高校名称") @RequestParam(value = "schoolName", required = false) String schoolName,
            @Parameter(description = "专业名称") @RequestParam(value = "majorName", required = false) String majorName,
            @Parameter(description = "是否严格匹配专业名称") @RequestParam(value = "majorNameStrict", required = false, defaultValue = "false") Boolean majorNameStrict,
            @Parameter(description = "专业ID") @RequestParam(value = "specialId", required = false) Integer specialId,
            @Parameter(description = "录取年份") @RequestParam(value = "year", required = false, defaultValue = "0") Integer year,
            @Parameter(description = "录取最低分查询条件") @RequestParam(value = "min", required = false, defaultValue = "0") Integer min,
            @Parameter(description = "专业所属的录取批次") @RequestParam(value = "batchName", required = false) String batchName,
            @Parameter(description = "专业所属的类型") @RequestParam(value = "typeName", required = false) String typeName,
            @Parameter(description = "高校唯一ID") @RequestParam(value = "schoolUuid", required = false) String schoolUuid,
            @Parameter(description = "录取最低分区间查询条件") @RequestParam(value = "minRange", required = false) String minRange,
            @Parameter(description = "选科要求筛选条件") @RequestParam(value = "subjectSelection", required = false) String subjectSelection) {

        // 构建请求参数
        MajorAdmissionQueryReqVO reqVO = new MajorAdmissionQueryReqVO();
        reqVO.setPageindex(pageIndex);
        reqVO.setPagesize(pageSize);
        reqVO.setEnrollprovince(enrollProvince);
        reqVO.setSchoolname(schoolName);
        reqVO.setMajorname(majorName);
        reqVO.setMajornamestrict(majorNameStrict);
        reqVO.setSpecialid(specialId);
        reqVO.setYear(year);



        reqVO.setMin(min);
        reqVO.setBatchname(batchName);
        reqVO.setTypename(typeName);
        reqVO.setSchooluuid(schoolUuid);
        reqVO.setMinrange(minRange);
        reqVO.setSubjectselection(subjectSelection);

        // 判断是否需要获取所有数据并保存到数据库
        boolean fetchAllAndSave = pageIndex == null || pageSize == null;
        Map<String, Object> result;

        if (fetchAllAndSave) {
            // 设置默认分页参数
            reqVO.setPageindex(1);
            reqVO.setPagesize(100); // 使用API允许的最大页面大小

//            String province = "上海,云南,内蒙古,北京,吉林,四川,天津,宁夏,安徽,山东,山西,广东,广西,新疆,江苏,江西,河北,河南,浙江,海南,湖北,湖南,甘肃,福建,西藏,贵州,辽宁,重庆,陕西,青海,黑龙江";
            String province = "安徽";
            List<MajorAdmissionInfo> allProvincesData = new ArrayList<>();
            int totalCount = 0;
            int distinctSchoolCount = 0;
            int processedProvinces = 0;
            int successfulProvinces = 0;

            for (String s : province.split(",")) {
                try {
                    log.info("开始处理省份: {}", s);
                    reqVO.setEnrollprovince(s);
                    // 获取所有页的数据
                    result = majorAdmissionService.getMajorAdmissionInfoAll(reqVO);
//
//                    // 判断是否查询成功
//                    Boolean success = (Boolean) result.get("success");
//                    if (Boolean.TRUE.equals(success)) {
//                        // 获取所有数据
//                        List<MajorAdmissionInfo> allAdmissionList = (List<MajorAdmissionInfo>) result.get("admissionList");
//
//                        // 保存数据到数据库
//                        try {
//                            int savedCount = majorAdmissionService.saveMajorAdmissionList(allAdmissionList);
//                            log.info("成功保存{}省份的{}条专业录取数据到数据库", s, savedCount);
//                        } catch (Exception e) {
//                            log.error("保存{}省份的专业录取数据到数据库失败", s, e);
//                        }
//
//                        // 汇总数据
//                        allProvincesData.addAll(allAdmissionList);
//                        totalCount += (Integer) result.get("totalCount");
//                        distinctSchoolCount += (Integer) result.get("distinctSchoolCount");
//                        successfulProvinces++;
//
//                        log.info("成功处理省份: {}，获取到{}条数据", s, allAdmissionList.size());
//                    } else {
//                        String message = (String) result.get("message");
//                        log.error("获取{}省份的专业录取数据失败: {}", s, message);
//                    }
                } catch (Exception e) {
                    log.error("处理{}省份时发生异常", s, e);
                }
                processedProvinces++;
            }

            log.info("所有省份处理完成！共处理{}个省份，成功{}个，获取到{}条数据",
                    processedProvinces, successfulProvinces, allProvincesData.size());

            // 构建响应VO
            MajorAdmissionQueryRespVO respVO = new MajorAdmissionQueryRespVO();
            respVO.setAdmissionList(allProvincesData);
            respVO.setTotalCount(totalCount);
            respVO.setDistinctSchoolCount(distinctSchoolCount);
            respVO.setPageIndex(1); // 因为返回了所有数据，所以页码固定为1
            respVO.setPageSize(allProvincesData.size()); // 页面大小就是所有数据的数量
            respVO.setTotalPages(1); // 因为返回了所有数据，所以总页数固定为1

            return CommonResult.success(respVO);
        } else {
            // 使用传入的分页参数查询单页数据
            result = majorAdmissionService.getMajorAdmissionInfo(reqVO);

            // 判断是否查询成功
            Boolean success = (Boolean) result.get("success");
            if (Boolean.TRUE.equals(success)) {
                // 获取当前页数据
                List<MajorAdmissionInfo> admissionList = (List<MajorAdmissionInfo>) result.get("admissionList");

                // 保存数据到数据库
                try {
                    int savedCount = majorAdmissionService.saveMajorAdmissionList(admissionList);
                    log.info("成功保存{}条专业录取数据到数据库", savedCount);
                } catch (Exception e) {
                    log.error("保存专业录取数据到数据库失败", e);
                    // 数据保存失败不影响API正常返回结果
                }

                // 构建响应VO
                MajorAdmissionQueryRespVO respVO = new MajorAdmissionQueryRespVO();
                respVO.setAdmissionList(admissionList);
                respVO.setTotalCount((Integer) result.get("totalCount"));
                respVO.setDistinctSchoolCount((Integer) result.get("distinctSchoolCount"));
                respVO.setPageIndex((Integer) result.get("pageIndex"));
                respVO.setPageSize((Integer) result.get("pageSize"));
                respVO.setTotalPages((Integer) result.get("totalPages"));

                return CommonResult.success(respVO);
            } else {
                String message = (String) result.get("message");
                return CommonResult.error(400, message);
            }
        }
    }

    @GetMapping("/fetch-all-provinces")
    @Operation(summary = "获取所有省份的专业录取数据")
    public CommonResult<String> fetchAllProvinces(
            @Parameter(description = "年份") @RequestParam(value = "year", required = false, defaultValue = "0") Integer year,
            @Parameter(description = "专业名称") @RequestParam(value = "majorName", required = false) String majorName,
            @Parameter(description = "高校名称") @RequestParam(value = "schoolName", required = false) String schoolName,
            @Parameter(description = "是否使用多线程") @RequestParam(value = "useMultiThread", required = false, defaultValue = "true") Boolean useMultiThread) {

        // 所有省份列表
        List<String> provinces = Arrays.asList("上海", "云南", "内蒙古", "北京", "台湾", "吉林", "四川", "天津", "宁夏", "安徽",
                "山东", "山西", "广东", "广西", "新疆", "江苏", "江西", "河北", "河南", "浙江", "海南", "湖北", "湖南",
                "甘肃", "福建", "西藏", "贵州", "辽宁", "重庆", "陕西", "青海", "香港", "黑龙江");

        int totalSaved = 0;
        int totalProvinces = provinces.size();
        int processedProvinces = 0;

        if (useMultiThread) {
            // 使用多线程处理
            int threadCount = Math.min(provinces.size(), 5); // 最多使用5个线程
            ExecutorService executorService = Executors.newFixedThreadPool(threadCount);

            try {
                List<CompletableFuture<Integer>> futures = new ArrayList<>();

                // 为每个省份创建一个异步任务
                for (String province : provinces) {
                    CompletableFuture<Integer> future = CompletableFuture.supplyAsync(() -> {
                        try {
                            log.info("开始获取{}省份的专业录取数据", province);
                            MajorAdmissionQueryReqVO reqVO = new MajorAdmissionQueryReqVO();
                            reqVO.setEnrollprovince(province);
                            reqVO.setYear(year);
                            reqVO.setMajorname(majorName);
                            reqVO.setSchoolname(schoolName);

                            // 获取所有页的数据
                            Map<String, Object> result = majorAdmissionService.getMajorAdmissionInfoAll(reqVO);

                            // 判断是否查询成功
                            Boolean success = (Boolean) result.get("success");
                            if (Boolean.TRUE.equals(success)) {
                                // 获取所有数据
                                List<MajorAdmissionInfo> allAdmissionList = (List<MajorAdmissionInfo>) result.get("admissionList");

                                // 保存数据到数据库
                                int savedCount = majorAdmissionService.saveMajorAdmissionList(allAdmissionList);
                                log.info("成功保存{}省份的{}条专业录取数据到数据库", province, savedCount);
                                return savedCount;
                            } else {
                                String message = (String) result.get("message");
                                log.error("获取{}省份的专业录取数据失败: {}", province, message);
                                return 0;
                            }
                        } catch (Exception e) {
                            log.error("处理{}省份的专业录取数据时发生异常", province, e);
                            return 0;
                        }
                    }, executorService);

                    futures.add(future);
                }

                // 等待所有任务完成并汇总结果
                CompletableFuture<Void> allFutures = CompletableFuture.allOf(futures.toArray(new CompletableFuture[0]));
                allFutures.join(); // 等待所有任务完成

                // 计算总保存数量
                for (CompletableFuture<Integer> future : futures) {
                    totalSaved += future.get();
                    processedProvinces++;
                }
            } catch (Exception e) {
                log.error("多线程获取专业录取数据时发生异常", e);
                return CommonResult.error(500, "获取数据过程中发生错误: " + e.getMessage());
            } finally {
                executorService.shutdown();
            }
        } else {
            // 使用单线程顺序处理
            for (String province : provinces) {
                try {
                    log.info("开始获取{}省份的专业录取数据", province);
                    MajorAdmissionQueryReqVO reqVO = new MajorAdmissionQueryReqVO();
                    reqVO.setEnrollprovince(province);
                    reqVO.setYear(year);
                    reqVO.setMajorname(majorName);
                    reqVO.setSchoolname(schoolName);

                    // 获取所有页的数据
                    Map<String, Object> result = majorAdmissionService.getMajorAdmissionInfoAll(reqVO);

                    // 判断是否查询成功
                    Boolean success = (Boolean) result.get("success");
                    if (Boolean.TRUE.equals(success)) {
                        // 获取所有数据
                        List<MajorAdmissionInfo> allAdmissionList = (List<MajorAdmissionInfo>) result.get("admissionList");

                        // 保存数据到数据库
                        int savedCount = majorAdmissionService.saveMajorAdmissionList(allAdmissionList);
                        log.info("成功保存{}省份的{}条专业录取数据到数据库", province, savedCount);
                        totalSaved += savedCount;
                    } else {
                        String message = (String) result.get("message");
                        log.error("获取{}省份的专业录取数据失败: {}", province, message);
                    }
                } catch (Exception e) {
                    log.error("处理{}省份的专业录取数据时发生异常", province, e);
                }
                processedProvinces++;
            }
        }

        String resultMessage = String.format("处理完成！共处理%d个省份，成功保存%d条专业录取数据到数据库。", processedProvinces, totalSaved);
        log.info(resultMessage);
        return CommonResult.success(resultMessage);
    }

    @PostMapping("/process-bracket-content")
    @Operation(summary = "批量处理专业录取表中的专业名称括号内容")
    public CommonResult<Map<String, Object>> processMajorAdmissionBracketContent(
            @Parameter(description = "每批处理数量", required = false) @RequestParam(value = "batchSize", defaultValue = "5000") Integer batchSize,
            @Parameter(description = "线程数量", required = false) @RequestParam(value = "threadCount", defaultValue = "4") Integer threadCount) {

        try {
            Map<String, Object> result = majorAdmissionService.batchProcessMajorNameBracketContent(batchSize, threadCount);
            return CommonResult.success(result);
        } catch (Exception e) {
            log.error("批量处理专业录取表专业名称括号内容失败", e);
            return CommonResult.error(500, "批量处理专业录取表专业名称括号内容失败: " + e.getMessage());
        }
    }
}
